package com.lmaor.project.commons.attribute.format;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.lmaor.project.commons.bytes.ByteIndexUtils;
/** 属性格式化工具
 *  
 */
public class AttributeFormatUtils extends ByteIndexUtils{

	public final static byte[] splitBytes = {-1,-1};
	public final static byte[] nullBytes = {0};
 	/** 将属性编码成bytes
	 * 
	 * @param charsetName
	 * @param ss
	 * @return
	 */
	public static byte[] encode(String charsetName,String...ss) {
		byte[][] bytecs = new byte[ss.length][];
		int length = 0;
		
		for (int i = 0; i < bytecs.length; i++) {
			if(ss[i] == null) {
				bytecs[i] = nullBytes;
			}else {
				bytecs[i] = ss[i].getBytes(Charset.forName(charsetName));
			}
			length+=bytecs[i].length+splitBytes.length;
		}
		byte[] result = new byte[length];
		int index = 0;
		for (int i = 0; i < bytecs.length; i++) {
			byte[] src = bytecs[i];
			int size = src.length;
			System.arraycopy(src, 0, result, index, size);
			index+=size;
			for (int j = 0; j < splitBytes.length; j++) {
				result[index++] = splitBytes[j];
			}
		}
		return result;
	}
	/** 将属性解码成集合
	 * 
	 * @param charsetName
	 * @param bs
	 * @return
	 */
	public static List<String> decode(String charsetName,byte[] bs) {
		List<String> ss = new ArrayList<>();
		int startIndex = 0;
		while(startIndex < bs.length) {
			int endIndex = indexOf(bs, splitBytes, startIndex);
			int length = endIndex - startIndex;
			if(endIndex == -1) {
				length = bs.length - startIndex;
			}
			String str = null;
			if(!equals(bs, startIndex, endIndex, nullBytes)) {
				str = new String(bs, startIndex, length, Charset.forName(charsetName));
			}
			ss.add(str);
			startIndex = endIndex+splitBytes.length;
		}
		return ss;
	}
	
	public static String attrMapToString(Map<String, String> map) {
		if(map == null) {
			return null;
		}
		StringBuilder result = new StringBuilder(100);
		map.forEach((k,v)->{
			result.append(k).append('\0').append(v).append('\0');
		});
		return result.toString();
	}
	public static Map<String, String> attrStringToMap(String text){
		return attrStringToMap(text, new HashMap<>());
	}
	public static <MAP extends Map<String, String>> MAP attrStringToMap(String text,MAP result){
		int index = -1;
		int endIndex = text.length() - 1;
		while(index!=endIndex) {
			int keyStartIndex = index+1;
			int keyEndIndex = text.indexOf('\0',keyStartIndex);
			if(keyEndIndex == -1) {
				break;
			}
			int valStartIndex = keyEndIndex+1;
			int valEndIndex = text.indexOf('\0', valStartIndex);
			if(valEndIndex == -1) {
				break;
			}
			String key = text.substring(keyStartIndex, keyEndIndex);
			String val = text.substring(valStartIndex, valEndIndex);
			result.put(key, val);
			index = valEndIndex;
		}
		
		return result;
	}
	
	public static void main(String[] args) {
		byte[] res = encode("UTF-8", "aaa","bbb",null,"c");
		System.out.println(Arrays.toString(res));
		System.out.println(equals(res, new byte[] {97, 97, 97, -1, -1, 98, 98, 98, -1, -1, 99, -1, -1}));
		System.out.println(indexOf(res, new byte[] {97,-1,-1},0));
		System.out.println(decode("UTF-8", res));
		System.out.println(Arrays.toString("\0".getBytes()));
		Map<String, String> map = new HashMap<>();
		map.put("a", "ax");
		map.put("fxyu2", "cccc");
		map.put("fxyu3", "cccc");
		String mapres = attrMapToString(map);
		System.out.println(mapres);
		System.out.println(attrStringToMap(mapres));
	}
	
}
